package ws

import (
	"apiManageGo/src/core/common/logs"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"go.uber.org/zap"
	"net"
	"net/http"
)

var Ws = new(ws)

type ws struct {
}

var upGrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func (i *ws) OpenWebSocket(ctx *gin.Context) {
	conn, err := upGrader.Upgrade(ctx.Writer, ctx.Request, nil)
	if err != nil {
		logs.Error("websocket error:", zap.Error(err))
		return
	}
	//得到客户的连接ip和端口
	logs.Info("client connect:", zap.String("remote", conn.RemoteAddr().String()))
	go i.Do(conn)
}
func (i *ws) Do(conn *websocket.Conn) {
	for {
		//获取到前端发送过来的websocket消息
		contentType, message, err := conn.ReadMessage()
		if err != nil {
			//判断是不是超时
			if netErr, ok := err.(net.Error); ok {
				if netErr.Timeout() {
					logs.Info("ReadMessage timeout remote:", zap.String("remote", conn.RemoteAddr().String()))

				}
			}
			// 其他错误，如果是 1001 和  1000，就不打印日志
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseNormalClosure) {

			}

			conn.Close()
			//这边必须return，因为前端的链接可能某个时间段就断开链接了，要是没有return，会导致产生 repeated read on failed websocket connection报错,而且也可以防止内存泄露
			return
		}

		logs.Info("contentType:", zap.String("contentType", string(contentType)))
		fmt.Println(string(message))

		//写入ws 给客户端返回成功
		msg := []byte("done")
		err = conn.WriteMessage(1, msg)
		if err != nil {
			logs.Info("WriteMessage error:", zap.String("remote", conn.RemoteAddr().String()))
		}
	}
}
